package com.shire.shire_interface.service.commandcenter.queues;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.shire.shire_interface.common.utils.ChatUtil;
import com.shire.shire_interface.constants.Constants;
import com.shire.shire_interface.constants.WxConstants;
import com.shire.shire_interface.constants.WxErrorCode;
import com.shire.shire_interface.dao.massmsg.WxMassMsgItemDao;
import com.shire.shire_interface.dao.massmsg.WxMassMsgTaskDao;
import com.shire.shire_interface.model.accounts.UserAccount;
import com.shire.shire_interface.model.command.WxCommand;
import com.shire.shire_interface.model.cs.WxChat;
import com.shire.shire_interface.model.friend.WxFriend;
import com.shire.shire_interface.model.group.WxGroup;
import com.shire.shire_interface.model.massmsg.WxMassMsgItem;
import com.shire.shire_interface.model.massmsg.WxMassMsgItemExample;
import com.shire.shire_interface.model.massmsg.WxMassMsgTask;
import com.shire.shire_interface.model.massmsg.WxMassMsgTaskExample;
import com.shire.shire_interface.model.user.WxAccount;
import com.shire.shire_interface.service.account.WxAccountService;
import com.shire.shire_interface.service.chat.WxChatService;
import com.shire.shire_interface.service.commandcenter.WxCommandService;
import com.shire.shire_interface.service.friend.WxFriendService;
import com.shire.shire_interface.service.group.WxGroupService;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class MassMessageCommandQueue extends GappedCommandQueue {

    @Resource
    private WxMassMsgItemDao massMsgItemDao;
    @Resource
    private WxMassMsgTaskDao massMsgTaskDao;
    @Resource
    private WxCommandService commandService;
    @Resource
    private WxChatService chatService;
    @Resource
    private WxGroupService groupService;
    @Resource
    private WxFriendService friendService;

    @Resource
    private WxAccountService accountService;


    private static MassMessageCommandQueue instance;
    @PostConstruct
    public void init(){
        instance = this;
//        loadAllDevice();
    }

    public static MassMessageCommandQueue getInstance(){
        return instance;
    }

    public MassMessageCommandQueue getQueueForAccount(WxAccount account){
        return new MassMessageCommandQueue(account,
                WxConstants.CmdPriority.MASSMSG,
                massMsgTaskDao,
                massMsgItemDao,
                commandService,
                chatService,
                groupService,
                friendService,
                accountService);
    }

    public MassMessageCommandQueue(){
        super();
    }

    public MassMessageCommandQueue(WxAccount wxAccount,
                                   WxConstants.CmdPriority priority,
                                   WxMassMsgTaskDao massMsgTaskDao,
                                   WxMassMsgItemDao massMsgItemDao,
                                   WxCommandService commandService,
                                   WxChatService chatService,
                                   WxGroupService groupService,
                                   WxFriendService friendService,
                                   WxAccountService accountService) {
        super(wxAccount, priority);

        this.massMsgItemDao = massMsgItemDao;
        this.massMsgTaskDao = massMsgTaskDao;
        this.commandService = commandService;
        this.chatService = chatService;
        this.groupService= groupService;
        this.friendService = friendService;
        this.accountService = accountService;
    }

    @Override
    public WxCommand getNextCommand() {


        return super.getNextCommand();
    }

    public synchronized List<WxCommand> getNextBatch(){
        List<WxCommand> cmdList = new ArrayList<>();
        synchronized (this.wxAccount.getWxid().intern()) {
            WxMassMsgTaskExample taskExample = new WxMassMsgTaskExample();
            List<UserAccount> userAccountList = accountService.getSystemUserByWxid(wxAccount.getWxid());
            List<Integer> idList = new ArrayList<>();
            for (UserAccount ua : userAccountList){
                idList.add(ua.getUserId());
            }
            taskExample.createCriteria().andCsidIn(idList).andStatusEqualTo(0);
            taskExample.setCheckFinished(true);
            taskExample.setCheckOverTime(true);
            taskExample.setLimitDate(new Date((new Date()).getTime() - 3600*1000 * 24 * 1)); //不处理3天以前的任务
            List<WxMassMsgTask> taskList = massMsgTaskDao.selectByExample(taskExample);

            for (WxMassMsgTask wxMassMsgTask : taskList) {
                if (wxMassMsgTask.getSendtime() != null && wxMassMsgTask.getSendtime().getTime() > (new Date()).getTime())
                    continue; //未到发送时间
                if (wxMassMsgTask.getCreatetime() != null && wxMassMsgTask.getCreatetime().getTime() + 1000 * 30 > (new Date()).getTime()){
                    continue;
                }
                if (wxMassMsgTask.getUpdatetime() == null || wxMassMsgTask.getBatchinterval()* 1000 + wxMassMsgTask.getUpdatetime().getTime() < (new Date()).getTime()) {
                    //间隔符合要求
                    WxMassMsgItemExample msgItemExample = new WxMassMsgItemExample();
                    msgItemExample.createCriteria().andFromaccountEqualTo(wxAccount.getWxid()).andRststatusEqualTo(-999).andTaskidEqualTo(wxMassMsgTask.getId());
                    List<WxMassMsgItem> msgItems = massMsgItemDao.selectByExample(msgItemExample);


                    //发送该任务的一个批次
                    int i = 0;
                    for (WxMassMsgItem msgItem : msgItems) {
                        if (wxMassMsgTask.getMsgcontent().startsWith("{")) {
                            JSONObject jsonObject = new JSONObject();

                            WxConstants.CmdType cmdType = ChatUtil.getMsgRepContent(wxMassMsgTask.getMsgcontent(), jsonObject, msgItem.getToaccount(), "", "");

                            WxCommand wxCommand = commandService.generateCmdObject(wxAccount.getCsid(),
                                    wxAccount.getId(),
                                    jsonObject.toJSONString(),
                                    WxConstants.CmdTaskType.MASSMSG,
                                    msgItem.getId(), cmdType, WxConstants.CmdPriority.MASSMSG);


                            msgItem.setRststatus(WxErrorCode.INIT_VALUE);
                            msgItem.setCmdid(wxCommand.getId().intValue());
                            massMsgItemDao.updateByPrimaryKey(msgItem);

                            wxMassMsgTask.setUpdatetime(new Date());
                            wxMassMsgTask.setSentcount(wxMassMsgTask.getSentcount() + 1);
                            massMsgTaskDao.updateByPrimaryKey(wxMassMsgTask);

                            cmdList.add(wxCommand);

                            WxChat chat = new WxChat();
                            chat.setWxaccount(wxAccount.getWxid());
                            chat.setMsgid(String.valueOf((new Date()).getTime()));
                            Object contact;
                            contact = setUpMsg(msgItem, chat);

                            chat.setChatfrom(WxConstants.ChatFrom.SELF.getCode());
                            chat.setContent(wxMassMsgTask.getMsgcontent());
                            chat.setMsgtype(WxConstants.MessageType.TEXT.getCode());
                            chat.setSendstatus(WxErrorCode.INIT_VALUE);
                            chat.setReadstatus(Constants.YesNo.YES.ordinal());
                            chat.setFromplat(0);
                            chat.setShowstatus(Constants.YesNo.YES.getCode());
                            chat.setCsid(wxAccount.getCsid());
                            chat.setCreatetime(new Date());
                            chat.setReadtime(new Date());
                            chat.setCmdid(wxCommand.getId());
                            chatService.saveChat(chat);
                            chatService.sendToKf(chat, contact);
                            i++;

                            if (i >= wxMassMsgTask.getBatchsize()) { //达到批次要求
                                break;
                            }
                        } else {
                            JSONObject jsonObject = new JSONObject();
                            JSONArray msgArray = ChatUtil.getBatchMsgReqContent(wxMassMsgTask.getMsgcontent());
                            jsonObject.put("messages", msgArray);
                            jsonObject.put("toUserWxId", msgItem.getToaccount());

                            WxCommand wxCommand = null;
                            if (msgArray.size()>0) {
                                wxCommand = commandService.generateCmdObject(wxAccount.getCsid(),
                                        wxAccount.getId(),
                                        jsonObject.toJSONString(),
                                        WxConstants.CmdTaskType.MASSMSG,
                                        msgItem.getId(),
                                        WxConstants.CmdType.CRK_SEND_CHAT_BATCH_D,
                                        WxConstants.CmdPriority.MASSMSG);
                                msgItem.setRststatus(WxErrorCode.INIT_VALUE);
                                msgItem.setCmdid(wxCommand.getId().intValue());
                                massMsgItemDao.updateByPrimaryKey(msgItem);

                                wxMassMsgTask.setUpdatetime(new Date());
                                wxMassMsgTask.setSentcount(wxMassMsgTask.getSentcount() + 1);
                                massMsgTaskDao.updateByPrimaryKey(wxMassMsgTask);

                                cmdList.add(wxCommand);
                            }


                            JSONArray newMsgArray = JSONArray.parseArray(wxMassMsgTask.getMsgcontent());
                            if (newMsgArray.size() != msgArray.size()){
                                for (Object o : newMsgArray){
                                    JSONObject msgObj = (JSONObject)o;
                                    WxConstants.MessageType type = WxConstants.MessageType.get(msgObj.getInteger("msgtype"));
                                    if (type == WxConstants.MessageType.GROUP_NOTICE){
                                        JSONObject reqObj = new JSONObject();
                                        reqObj.put("groupWxId", msgItem.getToaccount());
                                        reqObj.put("desc", msgObj.getString("content"));
                                        wxCommand = commandService.generateCmdObject(wxAccount.getCsid(),
                                                wxAccount.getId(),
                                                reqObj.toJSONString(),
                                                WxConstants.CmdTaskType.MASSMSG,
                                                msgItem.getId(),
                                                WxConstants.CmdType.CRK_UPDATE_GROUP_DESC_D,
                                                WxConstants.CmdPriority.MASSMSG);

                                        cmdList.add(wxCommand);

                                        msgObj.put("msgtype",1);
                                        msgObj.put("content", "【群公告】"+msgObj.getString("content"));
                                        msgArray.add(msgObj);

                                        msgItem.setRststatus(WxErrorCode.INIT_VALUE);
                                        msgItem.setCmdid(wxCommand.getId().intValue());
                                        massMsgItemDao.updateByPrimaryKey(msgItem);

                                        wxMassMsgTask.setUpdatetime(new Date());
                                        wxMassMsgTask.setSentcount(wxMassMsgTask.getSentcount() + 1);
                                        massMsgTaskDao.updateByPrimaryKey(wxMassMsgTask);

                                    }else if (type == WxConstants.MessageType.FORWARD_MSG){
                                        JSONObject reqObj = new JSONObject();
                                        reqObj.put("toWxId", msgItem.getToaccount());
                                        reqObj.put("localId", msgObj.getString("forwardMsgId"));
                                        reqObj.put("fromWxId", msgObj.getString("forwardWxid"));
                                        reqObj.put("addWxid", msgObj.getBoolean("addWxid"));
                                        wxCommand = commandService.generateCmdObject(wxAccount.getCsid(),
                                                wxAccount.getId(),
                                                reqObj.toJSONString(),
                                                WxConstants.CmdTaskType.MASSMSG,
                                                msgItem.getId(),
                                                WxConstants.CmdType.CRK_FORWARD_MESSAGE_D,
                                                WxConstants.CmdPriority.MASSMSG);

                                        cmdList.add(wxCommand);

                                        msgObj.put("msgtype",1);
                                        msgObj.put("content", "【转发消息】");
                                        msgArray.add(msgObj);

                                        msgItem.setRststatus(WxErrorCode.INIT_VALUE);
                                        msgItem.setCmdid(wxCommand.getId().intValue());
                                        massMsgItemDao.updateByPrimaryKey(msgItem);

                                        wxMassMsgTask.setUpdatetime(new Date());
                                        wxMassMsgTask.setSentcount(wxMassMsgTask.getSentcount() + 1);
                                        massMsgTaskDao.updateByPrimaryKey(wxMassMsgTask);

                                    }
                                }
                            }


                            for (Object o : newMsgArray) {
                                JSONObject msg = (JSONObject) o;
                                WxChat chat = new WxChat();
                                chat.setWxaccount(wxAccount.getWxid());
                                chat.setMsgid(String.valueOf((new Date()).getTime()));
                                Object contact;
                                contact = setUpMsg(msgItem, chat);

                                chat.setChatfrom(WxConstants.ChatFrom.SELF.getCode());
                                chat.setContent(msg.toJSONString());
                                chat.setMsgtype(WxConstants.MessageType.TEXT.getCode());
                                chat.setSendstatus(WxErrorCode.INIT_VALUE);
                                chat.setReadstatus(Constants.YesNo.YES.ordinal());
                                chat.setFromplat(0);
                                chat.setShowstatus(Constants.YesNo.YES.getCode());
                                chat.setCsid(wxAccount.getCsid());
                                chat.setCreatetime(new Date());
                                chat.setReadtime(new Date());
                                chat.setCmdid(wxCommand.getId());
                                chatService.saveChat(chat);
                                chatService.sendToKf(chat, contact);
                                i++;

                                if (i >= Math.min(30,wxMassMsgTask.getBatchsize())) { //达到批次要求
                                    break;
                                }
                            }
                        }
                    }

                }
            }
        }
        return cmdList;
    }

    private Object setUpMsg(WxMassMsgItem msgItem, WxChat chat) {
        Object contact;
        if (msgItem.getToaccount().endsWith("@chatroom")) {
            WxGroup group = groupService.selectGroupByNoForCs(wxAccount.getCsid(), wxAccount.getWxid(), msgItem.getToaccount());
            chat.setFriendwxid(group.getGroupno());
            chat.setFriendNick(group.getGroupname());
            chat.setAvatar(group.getAvatar());
            contact = group;
        } else {
            WxFriend friend = friendService.getFriendByWxId(wxAccount.getCsid(), wxAccount.getWxid(), msgItem.getToaccount());
            chat.setFriendwxid(friend.getFriendwxid());
            chat.setFriendNick(friend.getFriendnick());
            chat.setAvatar(friend.getAvatar());
            contact = friend;
        }
        return contact;
    }
}
